# 表格
import tkinter as tk
from tkinter import Scrollbar
from tkinter.ttk import Treeview
from tkinter import ttk
from tools import *
from sys_config import *
from tab_func import *

class TabGrid():
    #初始化：容器、查询列义
    def __init__(self, container, def_query):
        self.container  = container
        self.def_query  = def_query
        self.def_header = def_query['header']
        self.is_inited  = False   #是否已经初化
        self.tools      = Tools()
        self.tab_func   = TabFunc()
        self.config     = SysConfig()
        self.config.init()

        self.id_list         = []    #id字段值的列表
        self.last_search_str = ''   #上次搜索的文本
        self.last_search_num = 0    #上次搜索到的行号

    def create_tab(self, width_list):
        """初始化表格
            width_list  每个字符的宽度(px)，使用时加1
        """        
        print("create_tab", width_list)
        # 滚动条 声明
        scrollBarY = Scrollbar(self.container, orient='vertical')
        scrollBarX = Scrollbar(self.container, orient='horizontal')

        # Treeview组件，6列，显示表头，带垂直滚动条
        # _columns = ('c1', 'c2', 'c3', 'c4', 'c5', 'c6')
        _columns = []
        for i in range(len(self.def_header)):
            _columns.append(self.def_header[i]['field'])

        self.tree = Treeview(self.container,
                        columns=_columns,
                        show="",
                        yscrollcommand=scrollBarY.set)
        # show="headings" #表示显示表头
        # 滚动条
        scrollBarY.pack(side='right', fill='y')
        scrollBarY.config(command=self.tree.yview)
        scrollBarX.pack(side='bottom', fill='x')
        scrollBarX.config(command=self.tree.xview)

        # 设置每列宽度和对齐方式
        # self.tree.column('c1', width=70, anchor='center')
        for i in range(len(self.def_header)):
            _col = self.def_header[i]
            self.tree.column(_col['field'], 
                            #  width=int(char_width * _col['width'] * 0.96),     # 0.9846
                            width = width_list[i],
                             anchor=_col['align'])

        self.tree.pack(side='left', fill='both')
        self.tree.bind('<<TreeviewSelect>>', self.on_treeview_click)  #选中事件
        if self.def_query['multiselect'] == False: self.tree['selectmode'] = 'browse'  #只能选中一行
        self.is_inited = True

    # 生成演示数据
    def demo_data(self, width_list):
        if self.is_inited == False:
            self.create_tab(width_list)

        for i in range(1, 101):
            v = []
            # _tag = 'evenRow'
            # if (i % 2) == 0:
            #     _tag = 'oddRow'
            for j in range(len(self.def_header)):
                # v.append(self.tools.gen_string(str(j), 5))
                v.append(str(i) + '-' + str(j + 1))
                _cell = ''
                if j == 3: _cell = 'tag' + str(j)
                if j == 4: _cell = 'tag' + str(j)

            self.tree.insert('', i, values=v, tags=(_cell,))
            self.id_list.append('id-' + str(i))

        self.__prettify()
        self.style.configure('Treeview.Row.tag3', foreground='blue') #不起作用?
        self.style.configure('Treeview.Row.tag4', foreground='red')

    # 美化表格
    def __prettify(self):
        font_size = self.config.value('ui', 'font_size', 12)

        self.style = ttk.Style()
        self.style.map('Treeview', 
                    foreground=self.__fixed_map('foreground'), 
                    background=self.__fixed_map('background'))
        #定义背景色风格
        self.tree.tag_configure('even', background='lightblue') # even标签设定为浅蓝色背景颜色
        # print("__prettify row_height", type(self.def_query['row_height']), self.def_query['row_height'])
        self.style.configure('Treeview', rowheight=int(self.def_query['row_height']))  # 行高
        self.style.configure('Treeview', font=('宋体', font_size))  # 树状视图中的字体

        self.__tree_color() # 启动程序，根据奇偶行设为不同的背景颜色
    def __tree_color(self): # 表格栏隔行显示不同颜色函数
        items = self.tree.get_children() # 得到根目录所有行的iid
        i=0 # 初值
        for hiid in items:
            if i/2!=int(i/2): # 判断奇偶
                tag1='odd' # 奇数行
            else:
                tag1='even' # 偶数行
            self.tree.item(hiid,tag=tag1) # 偶数行设为浅蓝色的tag='even'
            i+=1 # 累加1
    def __fixed_map(self, option):
        return[elm for elm in self.style.map('Treeview', query_opt=option)
        if elm[:2]!=('!disabled','!selected')]

    #定义并绑定Treeview组件的鼠标单击事件
    def on_treeview_click(self, event):
        # 获取点击的项的ID和值
        selected_item = self.tree.selection()  # 获取选中的项的ID列表（通常是最后一个选中的项）
        if(selected_item):
            print("on_treeview_click 选中行数:", len(selected_item))
            item_id = selected_item[0]  # 获取ID（如果有多个项被选中，这里只取第一个）
            item_values = self.tree.item(item_id, 'values')  # 获取该项的值
            print(f"Clicked item ID: {item_id}, Values: {item_values}")
    
    def get_count(self):
        """取得行数
        """
        if self.is_inited == False: return 0
        
        return len(self.tree.get_children())
    
    def get_selected_count(self):
        """取得选中的行数
        """
        _count = self.get_count()
        if _count == 0: return 0
        
        selected_item = self.tree.selection()
        return len(selected_item)
    
    def get_selected_num(self):
        """取得选中的行号的列表(从1开始)
        """
        _count = self.get_count()
        if _count == 0: return []
        
        selected_item = self.tree.selection()
        ret = []
        if(selected_item):
            for item in selected_item:
                ret.append(self.tree.index(item) + 1)

        return ret
    
    
    def get_selected_id(self):
        """取得选中的id的列表
        """
        _count = self.get_count()
        if _count == 0 or len(self.id_list) == 0: return []
        
        selected_item = self.tree.selection()
        ret = []
        if(selected_item):
            for item in selected_item:
                ret.append(self.id_list[self.tree.index(item)])

        return ret
    
    def get_cell(self, num, col, del_return = False):
        """取得指定单元格的内容
        参数 Args:
            num  (int):  行号（从1开始）
            col  (int):  列号（从1开始）
            del_return  (bool):  删除换行符
            
        返回值 Returns:
            string:  
        """
        _count = self.get_count()
        if _count == 0 or num < 1 or num > _count: return ''

        item_id = self.tree.get_children()[num - 1]
        item_values = self.tree.item(item_id, 'values')  # 获取该项的值
        if col < 1 or col > len(item_values): return ''

        ret = item_values[col - 1]
        if del_return: ret = ret.replace("\n", '')
        return ret
    
    def get_selected_cell(self, col):
        """取得第一个选中行的指定单元格的内容
        参数 Args:
            col  (int):  列号（从1开始）
            
        返回值 Returns:
            string:  
        """
        _count = self.get_count()
        if _count == 0: return ''

        _num = self.get_selected_num()
        if len(_num) == 0: return ''
        return self.get_cell(_num[0], col, True)
    
    def search(self, search_str):
        """搜索，选中找到的行，返回找到的行号（从1开始）"""
        if search_str == '': return 0

        _count = self.get_count()
        if _count == 0: return 0
    
        if self.last_search_num == _count:      self.last_search_num = 0
        if self.last_search_str != search_str:  self.last_search_num = 0
        self.tree.selection_remove()

        num = self.__search(self.last_search_num, search_str)
        if num > 0:
            rows = self.tree.get_children()
            self.tree.selection_set(rows[num - 1])  # 高亮显示匹配的项
            self.tree.see(rows[num - 1])
        
        print("search_str num:", num, self.last_search_str, self.last_search_num)
        self.last_search_str = search_str
        self.last_search_num = num
        return num
                
    def __search(self, begin_num, search_str):
        """执行搜索
        参数 Args:
            begin_num   (float):    开始的行号
            search_str  (string):   搜索文本
            
        返回值 Returns:
            int:  选中找到的行号（从1开始）
        """
        if begin_num < 0 or search_str == '': return 0
    
        self.tree.selection_remove()
        rows = self.tree.get_children()
        for i in range(begin_num + 1, len(rows)):
            # if pattern in self.tree.item(item, "text"):  # 搜索文本
            #     self.tree.selection_set(item)  # 高亮显示匹配的项
            #     return True
            for value in self.tree.item(rows[i], "values"):  # 搜索值
                if search_str in value:
                    return i + 1
                
        return 0
    
    def clear(self):
        """清除所有行
        """
        _count = self.get_count()
        if _count == 0: return

        self.tree.delete(*self.tree.get_children())

    def delete(self, num):
        """删除指定行
        """
        _count = self.get_count()
        if _count == 0 or num < 1 or num > _count: return

        self.tree.delete(self.tree.get_children()[num - 1])
        self.__prettify()

    def delete2(self):
        """删除选中行
        """
        num = self.get_selected_num()
        if len(num) == 0: return

        num.reverse()
        for item in num:
             self.tree.delete(self.tree.get_children()[item - 1])
        self.__prettify()

    def set_data(self, data, width_list):
        """显示数据
        data
        width_list  int 每个字符的宽度px
        """
        if self.is_inited == False:
            self.create_tab(width_list)
        
        self.clear()
        if data == False: return False

        i = 0
        for row in data:
            v = []
            for j in range(len(self.def_header)):
                if self.def_header[j]['field'] == '_row_num_': #行号
                    v.append(i + 1)
                else:
                    s = row.get(self.def_header[j]['field'], '')
                    if len(str(s)) > 0 and len(self.def_header[j]['format']) > 0: #使用格式
                        s = self.tab_func.format_value(s, self.def_header[j]['format'])

                    _len = self.tools.str_len(s)    # 注意要考虑汉字的宽度

                    # print("set_data", self.def_header[j]['field'],s,self.def_header[j]['width'])
                    # print("set_data str_len", _len)
                    if _len > self.def_header[j]['width']:
                        s = self.tools.wrap_text_gbk(s, self.def_header[j]['width'])
                        # print("set_data wrap_text", s)
                    v.append(s)
            
            self.tree.insert('', i, values=v)
            if len(self.def_query['id_field']) > 0: self.id_list.append(row.get(self.def_query['id_field'], ''))
            i += 1

        self.__prettify()

